package com.sen.organization.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sen.common.common.response.PageVo;
import com.sen.common.common.util.SnowflakeIdWorker;
import com.sen.common.common.util.TreeUtils;
import com.sen.organization.bo.SearchDepartmentBo;
import com.sen.organization.dto.MemberDepartmentDTO;
import com.sen.organization.exception.MemberException;
import com.sen.organization.mapper.MemberDepartmentDao;
import com.sen.organization.model.MemberDepartment;
import com.sen.organization.service.DepartmentService;
import com.sen.organization.vo.MemberDepartmentVo;
import com.sen.rbac.constant.RbacConstant;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

import static com.sen.organization.enums.MemberEnum.add_department_failure;

/**
 * @author wr
 */
@Service
@Slf4j
public class DepartmentServiceImpl implements DepartmentService {

    @Resource
    MemberDepartmentDao departmentDao;

    @Resource
    ModelMapper modelMapper;


    @Override
    public Set<MemberDepartmentVo> listDepartTree(String entityCode) {
        Set<MemberDepartmentVo> voList = new TreeSet<>();
        List<MemberDepartment> departments = CollectionUtil.newArrayList();
        LambdaQueryWrapper<MemberDepartment> objectLambdaQueryWrapper = Wrappers.<MemberDepartment>lambdaQuery();
        if (StrUtil.isNotBlank(entityCode)) {
            objectLambdaQueryWrapper.like(MemberDepartment::getEntityCode, entityCode);
        }
        departments = departmentDao.selectList(objectLambdaQueryWrapper);

        List<MemberDepartmentVo> collect = departments.stream().map(p -> modelMapper.map(p, MemberDepartmentVo.class)).collect(Collectors.toList());
        for(MemberDepartmentVo vo:collect)
        {
            vo.setId(vo.getCode());
            vo.setName(vo.getDepartmentName());
        }
        TreeUtils.buildTree(RbacConstant.ROOT_CODE, collect, voList);
        return voList;
    }


    @Override
    public boolean addDepartment(MemberDepartmentDTO departmentDto) {
        String code=departmentDto.getCode();
        String entityCode=departmentDto.getEntityCode();
        MemberDepartment department = modelMapper.map(departmentDto, MemberDepartment.class);
        if(code==null) {
            MemberDepartment memberDepartment = departmentDao.selectOne(Wrappers.<MemberDepartment>lambdaQuery()
                    .eq(MemberDepartment::getEntityCode, entityCode)
                    .eq(MemberDepartment::getDepartmentNumber, departmentDto.getDepartmentNumber()).or(lam -> lam.eq(MemberDepartment::getDepartmentName, departmentDto.getDepartmentName())));
            if(memberDepartment!=null) {
                throw new MemberException(add_department_failure) ;
            }
            String departmentCode = SnowflakeIdWorker.generateStrId();
            department.setCode(departmentCode);
            return departmentDao.insert(department) == 1;
        }else {
            List<MemberDepartment> checkList = departmentDao.selectList(Wrappers.<MemberDepartment>lambdaQuery()
                    .eq(MemberDepartment::getEntityCode, entityCode)
                    .eq(MemberDepartment::getDepartmentNumber, departmentDto.getDepartmentNumber())
                    .or(lam -> lam.eq(MemberDepartment::getDepartmentName, departmentDto.getDepartmentName())));
            if (CollUtil.isNotEmpty(checkList)&& checkList.size()>1){
                throw new MemberException(add_department_failure) ;
            }
            return departmentDao.update(department, Wrappers.<MemberDepartment>lambdaQuery().eq(MemberDepartment::getCode, code)) == 1;
        }
    }


    @Override
    public PageVo<MemberDepartmentVo> list(MemberDepartmentDTO departmentSearchDTO) {
        PageVo<MemberDepartmentVo> departmentVOPageVo = new PageVo<>();
        String entityCode=departmentSearchDTO.getEntityCode();
        IPage<SearchDepartmentBo> pages = departmentDao.listSearchDepartment(new Page<>(departmentSearchDTO.getPage(), departmentSearchDTO.getPageSize()), departmentSearchDTO.getDepartmentName(),entityCode);
        List<SearchDepartmentBo> records = pages.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            departmentVOPageVo.setList(records.stream().map(record -> modelMapper.map(record, MemberDepartmentVo.class)).collect(Collectors.toList()));
            departmentVOPageVo.setTotal(pages.getTotal());
        }
        return departmentVOPageVo;
    }

    @Override
    public void del(String departmentCode) {
        departmentDao.delete(Wrappers.<MemberDepartment>lambdaQuery().eq(MemberDepartment::getCode, departmentCode));
    }

    @Override
    public MemberDepartmentVo getMemberDepartment(String code) {
        MemberDepartmentVo memberDepartmentVO = new MemberDepartmentVo();
        MemberDepartment memberDepartment = departmentDao.selectOne(Wrappers.<MemberDepartment>lambdaQuery().eq(MemberDepartment::getCode, code));
        String parentCode=memberDepartment.getParentCode();
        MemberDepartment parentDepartment = departmentDao.selectOne(Wrappers.<MemberDepartment>lambdaQuery().eq(MemberDepartment::getCode, parentCode));
        memberDepartmentVO= modelMapper.map(memberDepartment, MemberDepartmentVo.class);
        memberDepartmentVO.setParentDepartment(parentDepartment.getDepartmentName());
        return memberDepartmentVO;
    }
}
